<?php
namespace control;

class outStockListClass extends adIndexClass
{
    private const title       = '出库单';
    private const page        = 'outStockList';
    private const table       = 'inventory';
    private const tableMx     = 'inventory_detail';
    private const tableRecord = 'inventory_record';//库存变动记录
    private const workflow    = ['草稿', '已出库'];
    private const source      = ['生产领料', '销售出库'];
    private const qualityState  = ['无', '待质检', '已质检'];

    /**
     * 字段初始化
     */
    public function fieldInit(): array
    {
        $tr = [
            'orderNo'          => [
                'name'  => '出库单号',
                'width' => 200,
            ],
            'type' => [
                'name'  => '业务类型',
                'width' => 200,
            ],
            'sourceTargetName'  => [
                'name'  => '来往单位',
                'width' => 300,
                'sort' => 1,
            ],
            'orderDate'  => [
                'name'  => '出库时间',
                'width' => 200,
            ],
            'state'          => [
                'name'  => '状态',
                'width' => 200,
            ]
        ];
        return $tr;
    }

    /*列表页-查询条件*/
    public function homeOptions($isAsync = true)
    {
        //生成查询表单
        $html = $this->tableShow([
            [
                [
                    "业务类型" => select(["name" => "source", 'option' => self::source]),
                    "出库单号" => text(array("name" => "orderNo")),
                    "往来单位" => text(array('name' => 'sourceTargetName',"title" => '往来单位', 'id' => 'target')) .
                        hidden(array('name' => 'targetId')).
                        <<<eof
                            <script>
                            $("#target").bigAutocomplete({
                                    url:root + 'control/adIndex.html?cla=outStockList&fun=getTarget',
                                    callback:function(data){
                                        $("[name='targetId']").val(data.id);
                                    }
                                });
                            </script>
                        eof,
                ],
                [
                    "出库时间" => text(['name' => 'orderDate', 'laydate' => ['range' => '~', 'type' => 'date'],]),
                ],
            ]
        ],1);
        //返回
        if (!$isAsync) {
            return $html;
        } else {
            return json_encode(['html' => $html], 320);
        }
    }

    /**
     * 查询条件
     *
     * @return string
     */
    public function home(): string
    {
        $html = $this->homeOptions(false);
        //控件
        $button = "";
        if ($this->power(self::page, "export")) {
            $button .="<span class='spanButton' onclick=\"layer('importTemplate','exportFrame',{cla:'".self::page."',type:'待出库',classify:'待出库'})\">导出</span>";
        }
        $url = root . "control/adIndex.html?cla=" . self::page;
        $button .= "<span onclick=\"newIframe('" . self::title . "详情','" . $url . "&fun=edit')\" class='spanButton'>新增出库</span>\n";

        $button .= "
					<script>
                        function batchPutInStock() {
                            var list = $(\"[name='listId[]']:checked\")
                            const arrar = []
                            if(list.length  == 0) {
                                warn('请选择待出库单')
                            }else{
                                list.each(function () {
                                    arrar.push($(this).val())
                                })
                                const url = root + 'control/adIndex.html?cla=outStockList&fun=batchPutIn'
                                $.post(url, {ids:JSON.stringify(arrar)}, function (data) {
                                    if (data.warn == 2) {
                                        newIframe('出库单详情',data.href)
                                    } else {
                                        warn(data.warn);
                                    }
                                }, 'json');
                            }
                        }
                    </script>
				";
        return $this->homeFun($this->search($html, layout: 'pop', toolButton: $button));
    }

    /*列表页-查询结果*/
    public function homeSearch($workFlow = '待出库')
    {
        $where  = " `coid` = '" . self::$coid . "' AND `classify`=0  ";
        $equal = [
            'sourceTable' => match ($this->post('source')) {
                '生产领料'     => 'pick_order',
                '销售出库'     => 'sale_send_order',
                default       => '',
            },
        ];
        $like  = [
            'orderNo'  => $this->post('orderNo'),
            'targetId' => $this->post('targetId'),
        ];
        $where .= self::timeComparison($this->post('orderDate'), 'date', 'sourceDate');
        //生成查询语句
        $where .= search([
            "="    => $equal,
            "like" => $like,
        ]);
        //排序
        $orderBy = $this->listSort(array(
            "search"  => $this->post('list_sort_key') ?: 'time',
            "sort" => $this->post('list_sort') ?: "desc",
            "array"   => array(),
        ));
        $page = $this->page(["table" => self::table, "where" => $where, "order" => $orderBy['orderBy']]);
        $_SESSION[self::page][$workFlow]['sql'] = $page['sql'];
        //获取自定义字段参数
        $installSearch = $this->installSearch();
        $body          = [];
        //表格控件区
        $liButton = array(
            $this->checkAll("listForm", "listId")
        );
        //获取记录
        $url = root . "control/adIndex.html?cla=" . self::page;
        //获取记录
        foreach ($page['array'] as $array) {
            //列表控件
            $dominate  = [
                "box"    => [
                    "name" => "listId", "value" => $array['id'],
                ],
                "detail" => [
                    "title" => "出库详情", "click" => "newIframe('出库详情','" . $url . "&fun=detail&id=" . $array['id'] . "')",
                ],
            ];
            $liButton[] = $this->dominate($dominate);
            //本行初始化
            $row = [];
            foreach ($installSearch['key'] as $key) {
                switch ($key) {
                    case 'warehouse':
                        $warehouse = query('warehouse', " id = '$array[warehouseId]' ","name");
                        $row[] = $warehouse['name'];
                        break;
                    case 'targetId':
                        $row[] = self::getCompanyName($array['targetId']);
                        break;
                    case 'sourceDate':
                        $row[] = self::formatDate($array['sourceDate']);
                        break;
                    default:
                        $row[] = isset($array[$key]) && $array[$key] ? $array[$key] : '';
                }
            }
            $body[] = $row;
        }
        //控件
        $button = "";
        //生成页面
        $li = $this->li(array(
            "body" => $body,
            "install" => $installSearch,
            "button" => array("html" => $liButton),
            "orderBySign" => $orderBy,
            "page" => $page['para'],
        ));
        //返回
        $json['html'] = $page['hint'] . $button . "<form name='listForm'>" . $li . "</form>" . $page['button'];
        return json_encode($json, 320);
    }

    /*详情页*/
    public function detail(): string
    {
        $info = query(self::table, " coid = '" . self::$coid . "' AND id = '{$this->get('id')}'");
        if (empty($info['id'])) {
            $html = "未找到此出库单";
        } else {
            //菜单
            $data   = array(
                "id" => $info['id'],
            );
            $button = [];
            $button[] = [
                "name" => "打印条码",
                "type" => "弹出层",
                "cla"  => $this->get('cla'),
                "fun"  => "printEdit",
                "post" => ["id" => $info['id']],
            ];
            $sourceAlias = match ($info['sourceTable']) {
                'pick_order'    => "生产领料",
                'sale_send_order'    => "销售出库",
                default                 => '其他',
            };
            if ($info['sourceTable']) {
                $obj = query($info['sourceTable'], " id = '{$info['sourceId']}' ");
            } else {
                $obj['orderNo'] = $obj['text'] = $obj['orderDate'] = '';
            }
            $checkAll = $this->checkAll("detailForm", "listId");
            $mxtr[]   = [$checkAll, '物料编码', '物料名称', '规格型号', '单位', '提货重量（吨）', '起始液位', '终止液位', '实际出库重量（吨）'];
            $result   = find(array('table' => self::tableMx, 'where' => "orderId = '$info[id]' order by list"));
            $totalArr = ['orderNum'=>0,'num'=>0];

            $inStockQuality = optionSettingClass::getSettingItem('库存', 'outStockQuality');
            foreach ($result['array'] as $array) {
                //列表控件
                $dominate    = [
                    "box" => [
                        "name" => "listId", "value" => $array['id'],
                    ],
                ];
                if($array['quality'] == 1 && $inStockQuality){
                    unset($dominate['box']);
                }
                $material    = query('material', " id = '$array[materialId]'");
                $mxtr[] = [
                    $this->dominate($dominate),
                    $material['code'],
                    $material['name'],
                    $material['model'],
                    $array['unit'],
                    self::lostZero($array['weight'], 'numPrecision'),
                    self::lostZero($array['start_position'], 'numPrecision'),
                    self::lostZero($array['end_position'], 'numPrecision'),
                    self::lostZero($array['num'], 'numPrecision'),
                ];
            }
            $mxButton = '';
            if (in_array($info['state'], ['待出库', '部分出库'])) {
                $tip = $inStockQuality ? componentClass::tipComponent("出库前需要先完成质检，如果状态为待质检，则不能选择出库") : '';
                $mxButton .= <<<EOT
					<span class="smallButton" onclick="batchPutInStock('{$info['id']}')">批量出库</span>$tip
				EOT;
                $mxButton .= "
					<script>
                        function batchPutInStock(targetId) {
                            var list = $(\"[name='listId[]']:checked\")
                            var str = ''
                            const arrar = []
                            if(list.length  == 0) {
                                warn('请选择物料')
                            }else{
                                list.each(function () {
                                    arrar.push($(this).val())
                                })
                                str = arrar.join('/')
                                newIframe('出库单详情',root +'control/adIndex.html?cla=outStockList&fun=edit&targetId='+targetId+'&ids='+str+'&id='+str)
                            }
                        }
                    </script>
				";
            }
            //生成表单
            $data['button'] = $this->tableShowButton($button);
            $data['html'] = $this->tableShow([
                [
                    [
                        "业务类型" => $sourceAlias,
                        "往来单位" => self::getCompanyName($info['targetId']),
                        "单据日期" => self::formatDate($obj['orderDate'] ?? ''),
                    ],
                    [
                        "备注" => $obj['text'],
                        "出库单号" => $info['orderNo'],
                        "状态"     => $info['state'],
                    ],
                ]
            ]);
            $data['html'] .= $this->detailList([
                'title' => "明细",
                'button' => $mxButton,
                'html' => "<form name='detailForm'>".$this->listTable(array('tr' => $mxtr, 'showEmpty' => true, 'showSort' => true))."</form>",
            ]);
            //生成页面
            $html = $this->tab($data);
        }
        //返回
        return $html;
    }

    /**
     * 编辑页
     *
     * @return string
     */
    public function edit(): string
    {
        $id       = $this->get('id');
        $info     = query(self::table, " coid = '" . self::$coid . "' AND id = '" . $id . "' ");
        $button[] = [
            'style' => 'li-btn-blue-bg',
            "name"  => "保存",
            "type"  => "点击事件",
            "title" => "保存",
            'fun'   => "subForm('" . self::page . "EditForm','" . root . "control/adIndex.html?cla=" . self::page . "&fun=editEdit')",
        ];
        $tr[]     = ['',  '物料编码', '物料名称', '规格型号', '单位', '提货重量（吨）', '起始液位', '终止液位', '实际出库重量（吨）'];
        if ($this->get('ids')) {
            $id = $this->get('targetId');
            $target = query("inventory", " id = '" . $this->get('targetId') . "' ");
            //主表信息
            $info['type']             = $target['type'];
            $info['targetId']         = $target['targetId'];
            $info['sourceTargetName'] = self::getCompanyName($target['targetId']);

            $mxIdArr = array_filter(explode('/', $this->get('ids')));
            //是否自动生成批号
            //物料档案管理批号，并且公共设置批号自动生成，并且自动带出批号
            foreach ($mxIdArr as $k=>$detailId) {
                $inventory_detail             = query("inventory_detail", " id = '" . $detailId . "' ");
                if(optionSettingClass::getSettingItem('库存', 'outStockQuality') && $inventory_detail['quality'] == 1){
                    continue;
                }
                $material                     = query('material', "id = '$inventory_detail[materialId]'");
                $putIn                        = find(array(
                    'table'  => self::tableRecord,
                    'single' => "inventoryMxId = '$inventory_detail[id]'",
                    'field'  => " IFNULL(sum(num),0) as num "
                ));
                $notIn                        = $inventory_detail['orderNum'] - $putIn['num'];
                $inventory_detail['orderNum'] = self::lostZero($inventory_detail['orderNum'], 'numPrecision');
                $putIn['num']                 = self::lostZero($putIn['num'], 'numPrecision');
                $tr[]                         =
                    [
                        componentClass::tablePperation($k+1,"delTableRow(this);calculateTotal();").
                        hidden(['name' => 'mxId[]', 'value' => self::getId()]) .
                        hidden(['name' => 'materialId[]', 'value' => $material['id']]) .
                        hidden(['name' => 'unit[]', 'value' => $material['unit']]) .
                        hidden(['name' => 'sourceTable[]', 'value' => 'inventory_detail']) .
                        hidden(['name' => 'sourceId[]', 'value' => $detailId]),
//                        $inventory['orderNo'],
                    $material['code'],
                    $material['name'],
                    $material['model'],
                    $material['unit'],
                    text(array("name" => "weight[]", "value" => $notIn)),
                    readOnlyInput(array("name" => "start_position[]", "value" => $inventory_detail['start_position'])),
                    readOnlyInput(array("name" => "end_position[]", "value" => $inventory_detail['end_position'],'other' => "oninput='computeNum(this)'")),
                    text(array("name" => "num[]", "value" => $notIn)),
                ];
            }
        } else {
            $inventorySetting = optionSettingClass::getSetting('库存');
            $checkCtrl        = $inventorySetting['checkCtrl'];// 库存是否需要复核
            $result           = find(array('table' => self::tableMx, 'where' => "orderId = '$info[id]' order by list"));
            foreach ((array)$result['array'] as $k=>$array) {
                $material = query('material', " id = '$array[materialId]'");
                if ($info['state'] == '待出库') {
                    $del       = componentClass::tablePperation($k+1,"delTableRow(this);calculateTotal();");
                } else {
                    $del       = componentClass::tablePperation($k+1,"");
                }
                $num        = ($info['state'] == '待出库' || ($info['state'] == '已出库' && $checkCtrl)) ?
                    text(['name' => 'num[]', 'blur' => 'countMoney', 'value' => self::lostZero($array['num'], 'numPrecision'), 'other' => self::digitalFiltering('numPrecision')]) :
                    self::lostZero($array['num'], 'numPrecision');
                $tr[]       =
                    [
                        $del .
                        hidden(['name' => 'mxId[]', 'value' => $array['id']]) .
                        hidden(['name' => 'materialId[]', 'value' => $array['materialId']]) .
                        hidden(['name' => 'unit[]', 'value' => $array['unit']]) .
                        hidden(['name' => 'sourceTable[]', 'value' => $array['sourceTable']]) .
                        hidden(['name' => 'sourceId[]', 'value' => $array['sourceId']]),
//                        $array['sourceNo'],
                    $material['code'],
                    $material['name'],
                    $material['model'],
                    $array['unit'],
                    $array['weight'],
                    $array['start_position'],
                    $array['end_position'],
                    $num,
                ];
            }
        }

        $table = $this->listTable(array('tr' => $tr, 'end' => true));
        $page = self::page;
        $but  = '';
        if (!$info['state'] || $info['state'] == '待出库') {
            $but = "<span class='smallButton' onclick=\"layer('{$this->get('cla')}','addMx', $('form[name={$page}EditForm]').serialize())\">选择物料</span>";
        }
        //表单
        $data['button'] = $this->tableShowButton($button);
        $body = $this->edit4([
            '基本信息' => [
                [
                    must . "业务类型" => selectMultiple([
                        'option' => self::source,
                        "title"  => "请选择",
                        'name'   => 'type',
                        'value'  => $info['type']
                    ]),
                    "往来单位" => text(array(
                            'name'  => 'sourceTargetName',
                            'id'    => 'target',
                            'value' => $info['sourceTargetName']
                        )) .
                        hidden(array('name' => 'targetId', 'value' => $info['targetId'])) .
                        "<span class='del-row-button' onclick=\"newIframe('客户档案','" . root . "control/adIndex.html?cla=clientProfile&fun=edit')\" >新建客户</span>&nbsp;&nbsp;&nbsp;" .
                        "<span class='del-row-button' onclick=\"newIframe('供应商详情','" . root . "control/adIndex.html?cla=supplier&fun=edit')\" >新建供应商</span>",
                ],
                [
                    "单据时间" => text(['name' => "orderDate", 'laydate' => [], 'value' => $info['orderDate'] ?: $this->date]),
                    "备注"        => textarea(['name' => "text", 'class' => 'text', 'value' => $info['text']]),
                ],
            ]
        ]);
        $body .= $this->editList([
            'id' => 'materialTable',
            'title' => "明细",
            'button' => $but,
            'html' => $table,
        ]);
        $data['html'] = $this->pageEdit([
            "html"  => $body,
            'hidden' => hidden(['name' => 'id', 'value' => $id]),
        ]);
        $data['html'] .= <<<efo
<script>
$("#target").bigAutocomplete({
        url:root + 'control/adIndex.html?cla={$this->get('cla')}&fun=getTarget',
        callback:function(data){
            $("[name='targetId']").val(data.id);
        }
    });
function addRow(type=''){
    if(type == 'addWaitPutIn'){
        $.post(root+'control/adIndex.html?cla={$this->get('cla')}&fun=addWaitPutInEdit',$("form[name='orderForm']").serialize(),function(res) {
            $("#materialTable tbody").append(res.html);
            calculateTotal()
            resetNumber($("#materialTable"))
        },'json');
    }else{
        $.post(root+'control/adIndex.html?cla={$this->get('cla')}&fun=addMxEdit',$("form[name='mxForm']").serialize(),function(res) {
            $("#materialTable tbody").append(res.html);
            resetNumber($("#materialTable"))
        },'json');
    }
}
function chooseWait() {
    layer('{$this->get('cla')}','addWaitPutIn',$('form[name=outStockListEditForm]').serialize())
}
function computeNum(that) {
    var end_position = $(that).val(),
    start_position = $(that).parent().parent().find("[name='start_position[]']").val(),
    materialId = $(that).parent().parent().find("[name='materialId[]']").val(),
    num = $(that).parent().parent().find("[name='num[]']");
    $.post(root+'control/adIndex.html?cla={$this->get('cla')}&fun=getComputeNum',{start_position:start_position,end_position:end_position,materialId:materialId},function(res) {
        num.val(res.html);
    },'json');
}
function countMoney(e) {
    let currentKey = $(e).attr('name')
    let par = $(e).parent().parent()
    let numNode = par.find("[name='num[]']")
    let priceNode = par.find("[name='price[]']")
    let moneyNode = par.find("[name='money[]']")
    let num = numNode.val()*1
    let price = priceNode.val()*1
    let money = moneyNode.val()*1
    if(currentKey === 'num[]'){
        moneyNode.val((num * price).toFixed(amountPrecision)).trigger('input')
    }else if(currentKey === 'price[]'){
        moneyNode.val((num * price).toFixed(amountPrecision)).trigger('input')
    }else if(currentKey === 'money[]'){
        if(num > 0){
            priceNode.val((money / num).toFixed(publicSettings.pricePrecision.num)).trigger('input')
        }else if(price > 0){
            numNode.val((money / price).toFixed(publicSettings.numPrecision.num))
        }
    }
    calculateTotal()
}
//计算总金额，总税额
function calculateTotal(){
    let num = 0,
    money = 0;
    $(".editList").find("[name='num[]']").each(function(index){
        if($(this).val()){
          num+=Number($(this).val());
        }
        var moneyValue = $(".editList").find("[name='money[]']").eq(index).val()
        if(moneyValue){
            money+=Number(moneyValue);
        }
    })
    $(".numTotal").text(num.toFixed(publicSettings.numPrecision.num));
    $(".moneyTotal").text(money.toFixed(amountPrecision));
}
//根据仓库获取库位
function getPosition(e){
    let warehouseId = e.value;
    $.post(root+'control/adIndex.html?cla={$this->get('cla')}&fun=getPosition',{warehouseId:warehouseId},function(res) {
          $(e).parent().parent().find(".position").html(res.position);
    },'json');
}
</script>

efo;
        //返回
        return $this->tab($data);
    }

    /**获取往来单位名称
     *
     * @param string $targetId
     * @return string
     */
    final public static function getCompanyName($targetId = ''): string
    {
        $target = '';
        if ($targetId) {
            $target = query('kehu', " khid = '$targetId' ")['companyName'];
            if (empty($target)) {
                $target = query('supplier', " id = '$targetId' ")['name'];
            }
        }
        return $target;
    }

    /**
     * 模糊查询往来单位
     *
     * @return bool|string
     */
    public function getTarget(): bool|string
    {
        $val          = $this->post('keyword');//关键词
        $json['warn'] = 0;
        $json['data'] = [];
        $where        = $where2 = '';
        if (!empty($val)) {
            $where  = " and (companyName like '%" . $val . "%' or orderNo like '%" . $val . "%')";
            $where2 = " and (name like '%" . $val . "%' or code like '%" . $val . "%')";
        }
        $res = self::sqlFind(" select khid as id,concat(orderNo,'-',companyName) as name from kehu where coid = '" . self::$coid . "' {$where} UNION ALL select id,concat(code,'-',name) as name from supplier where coid = '" . self::$coid . "' {$where2} ");
        foreach ($res as $val) {
            $json['data'][] = array(
                'title' => $val['name'],
                'id'    => $val['id'],
            );
        }
        $json['warn'] = 2;
        return json_encode($json, 320);
    }

    /**
     * @return string
     */
    public function addMx(): string
    {
        $materialClassObj = new materialClass();
        $layerId          = $this->get('cla') . ucwords($this->get('fun'));
        $formName         = 'mxForm';
        $notAllowRepeat   = '';
        $data             = [
            'sub'            => " onclick=\"addRow();$('#" . $layerId . "').remove()\" ",
            'continueAdding' => $notAllowRepeat ? " onclick=\"addRow();removeSelectedContent('" . $formName . "')\" " : " onclick=\"addRow();\" ",
            'hidden'         => hidden(["name" => "type", "value" => $this->post('type')])
                . hidden(["name" => "targetId", "value" => $this->post('targetId')]) .
                hidden(array('name' => 'materialId', 'value' => $this->post('materialId') ? implode(',', $this->post('materialId')) : '')),
        ];
        return $materialClassObj->addMx($data);
    }

    /**
     * 编辑
     *
     * @return bool|string
     */
    public function addMxEdit()
    {
        $mxIdArr = $this->post('mxId');
        if (!$this->power(self::page, 'edit')) {
            $json['warn'] = "你没有编辑入库单的权限";
        } elseif (empty($mxIdArr) || !is_array($mxIdArr)) {
            $json['warn'] = "请选择物料";
        } else {
            $tr = [];
            //是否自动生成批号
            foreach ($mxIdArr as $mxId) {
                $material = query('material', "id = '$mxId'");
                $id           = self::getId();
                $tr[]       =
                    [
                        componentClass::tablePperation('',"delTableRow(this);calculateTotal();").
                        hidden(['name' => 'mxId[]', 'value' => $id]) .
                        hidden(['name' => 'materialId[]', 'value' => $mxId]) .
                        hidden(['name' => 'unit[]', 'value' => $material['unit']]) .
                        hidden(['name' => 'sourceTable[]', 'value' => '']) .
                        hidden(['name' => 'sourceId[]', 'value' => '']),
                        $material['code'],
                        $material['name'],
                        $material['model'],
                        $material['unit'],
                        text(['name' => 'weight[]', 'value' => '']),
                        text(['name' => 'start_position[]', 'value' => '']),
                        text(['name' => 'end_position[]', 'value' => '']),
                        text(['name' => 'num[]', 'value' => '']),
                    ];
            }
            $json['warn'] = 2;
            $json['html'] = $this->tableMany(['tr' => $tr, 'thead' => false]);
        }
        return json_encode($json, 320);
    }

    public function editEdit()
    {

        $id                  = $this->post('id') ?: static::getId();
        $mxIdArr        = $this->post('mxId') ?: [];
        $materialIdArr  = $this->post('materialId');
        $unitArr        = $this->post('unit');
        $warehouseArr   = $this->post('warehouseId');
        $positionIdArr  = $this->post('positionId');
        $numArr         = $this->post('num');
        $priceArr       = $this->post('price');
        $batchArr       = $this->post('batch');
        $sourceTableArr = $this->post('sourceTable');
        $sourceIdArr    = $this->post('sourceId');
        $weightArr    = $this->post('weight');
        $startPositionArr    = $this->post('start_position');
        $endPositionArr    = $this->post('end_position');
        $field      = [
            'type'             => $this->post('type'),
            'sourceTargetName' => $this->post('sourceTargetName'),
            'targetId'         => $this->post('targetId'),
            'orderDate'       => $this->post('recordDate'),
            'text'             => $this->post('text'),
            'state'    => '已出库',
        ];
        $annotation = [
            'type'     => "业务类型",
            'targetId' => "业务类型",
            'text'     => "备注",
        ];
        $rules      = [
            'type' => 'required',
        ];
        // 校验是否符合规则
        $vt     = new \verify();
        $result = $vt->setAliases($annotation)->validate($field, $rules)->isOk();
        if ($result === false) {
            $json['warn'] = $vt->getErrs()[0]; // 多个规则提示最前面一条
            goto resp;
        }
        $where     = " id = '$id' ";
        $info      = query(static::table, $where);
        $checkCtrl = optionSettingClass::getSettingItem('库存', 'checkCtrl');// 库存是否需要复核
        //判断
        if (!$this->power(self::page, "edit")) {
            $json['warn'] = "你没有编辑出库单的权限";
        } elseif (static::is_null_array($mxIdArr)) {
            $json['warn'] = "请选择出库明细";
        } elseif (static::is_null_array($materialIdArr)) {
            $json['warn'] = "请选择出库明细";
        } elseif (static::is_null_array($numArr, false)) {
            $json['warn'] = '数量请填写完整，且不能为0';
        } elseif (!empty($info['id']) && (in_array($info['state'], ['已复核', '已作废']) || (!$checkCtrl && $info['state'] == '已出库'))) {
            $json['warn'] = "此出库单为已复核或已作废状态，不能修改";
        } else {
            $this->startTrans();
            $isPass = true;//事务通过标志
            //更新基础数据
            if (!$info['id']) {
                $orderNo      = codeTemplateClass::generateCode(static::page, [
                    'prefix' => 'CKD' . date('Ymd'),
                    'table'  => static::table,
                    'field'  => 'orderNo',
                    'where'  => " AND coid = '" . static::$coid . "' ",
                ], $field);
                $field        = array_merge($field, [
                    'id'       => $id,
                    'orderNo'  => $orderNo,
                    'classify' => 0,
                    'state'    => '已出库',
                    'coid'     => static::$coid,
                    'stid'     => $this->control['stid'],
                    'time'     => $this->post('recordDate') ?: $this->time,
                ]);
                $json['warn'] = static::insert(["table" => static::table, "field" => $field,]);
            } else {
                $json['warn'] = static::update([
                    "table" => static::table,
                    "field" => $field,
                    "where" => $where,
                ]);
            }
            //添加或更新明细
            if (is_array($mxIdArr)) {
                foreach ($mxIdArr as $k => $nid) {
                    $mx = query(static::tableMx, "id = '$nid'");
                    //获取源单数据
                    $orderNum = 0;
                    $sourceNo = "";
                    $price    = $priceArr[$k] ?? 0;
                    if (!empty($sourceIdArr[$k])) {
                        $source    = query($sourceTableArr[$k], "id = '$sourceIdArr[$k]'");
                        $inventory = query("inventory", "id = '$source[orderId]'");
                        $orderNum  = $source['orderNum'];
                        $sourceNo  = $inventory['orderNo'];
                        $price     = inventoryBalanceClass::unitPrice($materialIdArr[$k]);  //出库均价
                    }

                    $numArr[$k] = static::formattingFigure($numArr[$k], 'numPrecision');
                    if (!empty($mx['id'])) {
                        //更新
                        $warn = static::update([
                            "table" => static::tableMx,
                            "field" => [
                                'warehouseId'      => $warehouseArr[$k],
                                'positionId'       => $positionIdArr[$k],
                                'num'              => $numArr[$k],
                                'batch'            => $batchArr[$k],
                                'price'            => $price,
                                'money'            => self::formattingFigure($price * $numArr[$k]),
                            ],
                            "where" => " id = '$nid'",
                        ]);
                        //未复核前可以修改出库数量
                        if ($info['state'] == '已出库') {
                            // 转换主单位
                            $editNum = $mainUnitNum = inventoryBalanceClass::toMainUnit($mx['materialId'], $numArr[$k], $mx['unit']);
                            //修改已出库记录数量
                            $result = query(static::tableRecord, " changesId = '$nid' and num < 0 ");
                            static::update([
                                "table" => static::tableRecord,
                                "field" => [
                                    'num' => -1 * $editNum,
                                ],
                                "where" => " id = '{$result['id']}' and coid = '" . static::$coid . "' ",
                            ]);
                            //如果关联了源单，则进行源单相关数据处理
                            if (!empty($sourceIdArr[$k])) {
                                //修改线边库存
                                static::update([
                                    "table" => 'line_inventory',
                                    "field" => [
                                        'num' => -$mainUnitNum,
                                    ],
                                    "where" => " changesId = '$nid' and coid = '" . static::$coid . "' ",
                                ]);
                                //更新账户变动记录
                                $money  = round($numArr[$k] * $source['price'] * (1 + $source['rate']), 2);
                                $record = find(array(
                                    'table'  => 'record',
                                    'single' => " changesId = '$nid' and coid = '" . static::$coid . "' ",
                                    'field'  => " IFNULL(sum(money),0) as total "
                                ));
                                $total  = abs($record['total']);
                                // 关联表
                                $targetDate = $inventory['orderDate'];
                                $targetNo   = $targetText = $hiddenText = ' ';
                                if ($inventory['sourceTable']) {
                                    $obj = query($inventory['sourceTable'], " id = '{$inventory['sourceId']}' ");
                                    if (!empty($obj['id'])) {
                                        $targetDate = $obj['recordDate'];
                                        $targetNo   = $obj['orderNo'];
                                        $targetText = $inventory['type'] . "单【{$obj['orderNo']}】";
                                        $hiddenText = $inventory['type'] . '单ID：' . $obj['id'] . '，出库单ID：' . $source['orderId'] . '出库单子ID：' . $source['id'];
                                    }
                                }
                                if ($record['total'] < 0) {
                                    $changeMoney = $money > $total ? $money - $total : -($total - $money);
                                } else {
                                    $changeMoney = $money - $total;
                                }
                                $bool = supplierClass::insertRecord(
                                    $inventory['targetId'],
                                    $inventory['type'],
                                    $changeMoney,
                                    'inventory_detail',
                                    $source['id'],
                                    $targetDate,
                                    $targetNo,
                                    $targetText,
                                    $hiddenText,
                                    $nid
                                );
                                if ($bool !== true) {
                                    $json['warn'] = $bool;
                                    goto resp;
                                }
                                //修改源单出库状态
                                $outNum      = $source['num'] - $mx['num'] + $numArr[$k];
                                $detailMoney = self::formattingFigure($outNum * $source['price'] * (1 + $source['rate']));
                                static::update([
                                    'table' => 'inventory_detail',
                                    'field' => [
                                        'num'   => $outNum,
                                        'money' => $detailMoney,
                                    ],
                                    'where' => " id = '{$source['id']}' ",
                                ]);
                                $notOut = find(array(
                                    'table'  => 'inventory_detail',
                                    'single' => "orderId = '$inventory[id]' and num < orderNum and coid = '" . static::$coid . "' and id <> '" . $source['id'] . "'",
                                    'field'  => " IFNULL(count(id),0) as num "
                                ));
//                                if ($outNum >= $source['orderNum'] && $notOut['num'] == 0) {
//                                    static::update([
//                                        'table' => 'inventory',
//                                        'field' => [
//                                            'state'       => '已出库',
//                                            'confirmTime' => $info['confirmTime'],
//                                        ],
//                                        'where' => " id = '{$inventory['id']}' ",
//                                    ]);
//                                } elseif ($inventory['state'] != '部分出库') {
//                                    static::update([
//                                        'table' => 'inventory',
//                                        'field' => [
//                                            'state'      => '部分出库',
//                                            'commitTime' => $this->time,
//                                        ],
//                                        'where' => " id = '{$inventory['id']}' ",
//                                    ]);
//                                }
                            }
                        }
                    } else {
                        //新增
                        $warn = static::insert([
                            "table" => static::tableMx,
                            "field" => [
                                'id'          => $nid,
                                'coid'        => self::$coid,
                                'orderId'     => $id,
                                'materialId'  => $materialIdArr[$k],
                                'orderNum'    => $orderNum,
                                'num'         => $numArr[$k],
                                'unit'        => $unitArr[$k],
                                'price'       => $price,
                                'money'       => self::formattingFigure($price * $numArr[$k]),
                                'warehouseId' => $warehouseArr[$k] ?? '',
                                'positionId'  => $positionIdArr[$k]?? '',
                                'sourceTable' => $sourceTableArr[$k],
                                'sourceId'    => $sourceIdArr[$k],
                                'weight'    => $weightArr[$k],
                                'start_position'    => $startPositionArr[$k],
                                'end_position'    => $endPositionArr[$k],
                            ],
                        ]);
                    }
                    if (!in_array($warn, ['新增成功', '更新成功'])) {
                        $isPass       = false;
                        $json['warn'] = $warn;
                        break;
                    }
                }
            }
            if (in_array($json['warn'], ["新增成功", "更新成功"]) && $isPass) {
                $this->commitTrans();
                delete(['table' => static::tableMx, 'where' => " id not in ('" . implode("','", $mxIdArr) . "') and orderId = '$id'"]);
                //添加日志
                $type = mb_substr($json['warn'], 0, 2, 'utf-8');
                $text = str_replace(['{{staffName}}', '{{type}}', '{{id}}'], [$this->control['name'], $type, $id], lang('outStockExec.editEdit.log'));
                $this->logText(["type" => static::page, "text" => $text]);
                //返回
                $_SESSION['warn'] = $json['warn'];
                $json['warn']     = 2;
                $json['href']     = root . "control/adIndex.html?cla=" . static::page . "&fun=detail&id=" . $id;
            } else {
                $this->rollback();
            }
        }

        resp:
        return json_encode($json, 320);
    }
    public function getComputeNum()
    {
        $start_position = $this->post('start_position');
        $end_position = $this->post('end_position');
        $materialId = $this->post('materialId');
        $liquid_ammonia = find(['table' => 'liquid_ammonia',"where"=>"materialId='$materialId' and (liquid_level='$start_position' or liquid_level='$end_position')"]);
        $num = 0;
        if($liquid_ammonia){
            $liquid_ammonia = array_column($liquid_ammonia['array'],'weight');
            $num = max($liquid_ammonia) - min($liquid_ammonia);
        }
        $json['warn'] = 2;
        $json['html'] = $num;
        return json_encode($json, 320);
    }

}